﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace GDD2_Game3
{
    class GameDraw : IDraw
    {
		private Game1 game1;
		private GameData gameData;
        private SpriteBatch spriteBatch;
		private Texture2D vehicleTexture;
		private Texture2D wallTexture;
        private Texture2D finishLineTexture;
		private Texture2D whiteTexture;
		private Texture2D powerUpTexture;
		private SpriteFont spriteFont;
		private const float GAME_SCALE = 1.0f;

		public GameDraw(Game1 g1, GameData data, SpriteBatch sb, Texture2D vehicle, Texture2D wall, Texture2D finishLine, Texture2D white, Texture2D powerUp, SpriteFont font)
        {
			game1 = g1;
			gameData = data;
			spriteBatch = sb;
			vehicleTexture = vehicle;
			wallTexture = wall;
            finishLineTexture = finishLine;
			whiteTexture = white;
			powerUpTexture = powerUp;
			spriteFont = font;
        }

        public void draw(GameTime gameTime)
        {
			//Vector2 cameraOffset = -gameData.Vehicle.Box.Center + new Vector2(game1.GraphicsDevice.Viewport.Width / 2.0f, game1.GraphicsDevice.Viewport.Height / 2.0f);
			spriteBatch.Begin();
            foreach (FinishLine finish in gameData.Track.Finish)
            {
                spriteBatch.Draw(finishLineTexture, cameraTransformationFloatBox(scaleGame(finish.Box)).Rectangle, Color.White);
            }
            foreach (Wall wall in gameData.Track.Walls)
            {
				spriteBatch.Draw(wallTexture, cameraTransformationFloatBox(scaleGame(wall.Box)).Rectangle, Color.White);
            }
			foreach(PowerUp pu in gameData.Track.PowerUps)
			{
				spriteBatch.Draw(powerUpTexture, cameraTransformationFloatBox(scaleGame(pu.Box)).Rectangle, pu.Enabled ? Color.White : Color.Gray);
			}
			Vector2 textureScaleFactor = scaleTexture(gameData.Vehicle.Box, vehicleTexture);
			spriteBatch.Draw(vehicleTexture, cameraTransformationVector2(gameData.Vehicle.Box.Center * GAME_SCALE), null, Color.White, gameData.Vehicle.Rotation, gameData.Vehicle.Box.Dimensions * GAME_SCALE / textureScaleFactor / 2.0f, textureScaleFactor, SpriteEffects.None, 0);
			spriteBatch.DrawString(spriteFont, gameData.PreviousEffectMessage, new Vector2(25.0f, gameData.ScreenDimensions.Y - 100.0f), Color.Yellow, 0.0f, Vector2.Zero, 0.18f, SpriteEffects.None, 0);
			if(gameData.IsFinished)
			{
				spriteBatch.Draw(whiteTexture, Vector2.Zero, null, Color.White, 0.0f, Vector2.Zero, gameData.ScreenDimensions, SpriteEffects.None, 0);
				spriteBatch.DrawString(spriteFont, string.Format("Time: {0:F2} seconds" + (gameData.Fooled ? "\nyou got 2 seconds off your actual time\nbecause \"Nothing Happened\"" : string.Empty), gameData.GameTime), Vector2.One * 200.0f, Color.Black, 0.0f, Vector2.Zero, 0.25f, SpriteEffects.None, 0);
			}
			spriteBatch.End();
        }

		private Vector2 cameraTransformationVector2(Vector2 pos)
		{
			Vector2 modifiedVehiclePosition = Vector2.Clamp(gameData.Vehicle.Box.Center * GAME_SCALE, gameData.ScreenDimensions / 2.0f, gameData.Track.Dimensions * GAME_SCALE - gameData.ScreenDimensions / 2.0f);
			return pos - modifiedVehiclePosition + gameData.ScreenDimensions / 2.0f;
		}

		private FloatBox cameraTransformationFloatBox(FloatBox fb)
		{
			Vector2 newCenter = cameraTransformationVector2(fb.Center);
			return fb.ShiftedBy(newCenter - fb.Center);
		}

		private FloatBox scaleGame(FloatBox destFB)
		{
			return destFB.ScaledBy(GAME_SCALE);
		}

		private Vector2 scaleTexture(FloatBox dataSize, Texture2D texture)
		{
			return dataSize.Dimensions * GAME_SCALE / new Vector2(texture.Width, texture.Height);
		}
    }
}
